﻿using SpecialEffects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using GlobalGameClasses;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Audio;



namespace SirianTestEnvironment
{
    
    
    /// <summary>
    ///Dies ist eine Testklasse für "BasicExplosionTest" und soll
    ///alle BasicExplosionTest Komponententests enthalten.
    ///</summary>
    [TestClass()]
    public class BasicExplosionTest
    {


        private TestContext testContextInstance;


        /// <summary>
        ///Ruft den Testkontext auf, der Informationen
        ///über und Funktionalität für den aktuellen Testlauf bietet, oder legt diesen fest.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional attributes for testing
        /// <summary>
        /// Initializes the required attributes for the test methods of this test class.
        /// </summary>
        /// <param name="testContext"></param>
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            System.Windows.Forms.Form form = new System.Windows.Forms.Form();
            form.Visible = false;
            form.ShowInTaskbar = false;
            PresentationParameters param = new PresentationParameters();
            param.DeviceWindowHandle = form.Handle;
            param.IsFullScreen = false;
            GraphicsDevice device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.HiDef, param);

            Texture2D explosionTex;
            string filePath1 = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) + "\\Out\\explosion.png";
            System.IO.FileStream fs1 = new System.IO.FileStream(filePath1, System.IO.FileMode.Open);
            explosionTex = Texture2D.FromStream(device, fs1);

            SoundEffect explosionSound;
            string filePath2 = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) + "\\Out\\explosionSound.wav";
            System.IO.FileStream fs2 = new System.IO.FileStream(filePath2, System.IO.FileMode.Open);
            explosionSound = SoundEffect.FromStream(fs2);

            Texture2D smokeTex;
            string filePath3 = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) + "\\Out\\smoke.png";
            System.IO.FileStream fs3 = new System.IO.FileStream(filePath3, System.IO.FileMode.Open);
            smokeTex = Texture2D.FromStream(device, fs3);

            TimeSpan totalGameTime = new TimeSpan(0, 0, 0, 0, 5000);
            TimeSpan elapsedGameTime = new TimeSpan(0, 0, 0, 0, 100);
            GameTime gameTime = new GameTime(totalGameTime, elapsedGameTime);

            GlobalGameValues.Values.content.Textures.Clear();
            GlobalGameValues.Values.content.GameSounds.Clear();
            GlobalGameValues.Values.graphicsDevice = device;
            GlobalGameValues.Values.content.addTexture("normalExplosion", explosionTex);
            GlobalGameValues.Values.content.addTexture("blueExplosion", explosionTex);
            GlobalGameValues.Values.content.addTexture("greenExplosion", explosionTex);
            GlobalGameValues.Values.content.addTexture("purpleExplosion", explosionTex);
            GlobalGameValues.Values.content.addTexture("redExplosion", explosionTex);
            GlobalGameValues.Values.content.addTexture("yellowExplosion", explosionTex);
            GlobalGameValues.Values.content.addSound("explosionSound", explosionSound);
            GlobalGameValues.Values.content.addTexture("missileExplosion", explosionTex);
            GlobalGameValues.Values.content.addTexture("smokeTexture", smokeTex);
            GlobalGameValues.Values.gameTime = gameTime;
            GlobalGameValues.Values.soundPlayer = (ISoundPlayer)DummySoundPlayer.GetSoundPlayer();
            
            fs1.Close();
            fs2.Close();
            fs3.Close();

        }
        
        #endregion


        /// <summary>
        ///Test for "CreateExplosionVertices"
        ///</summary>
        [TestMethod()]
        [DeploymentItem("SirianGame.exe")]
        public void CreateExplosionVerticesTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion explosion = BasicExplosion.CreateExpl_Enemy1(startPos, objectDirection, birthTime);
            Assert.IsTrue(explosion.deviceVertexBuffer != null);
            Assert.IsTrue(explosion.explosionVertices != null);
            Assert.IsTrue(explosion.explosionVertices.Length == 6 * (2 * Explosion.EXPL_PARTICLE_GW));

        }


        /// <summary>
        ///Test for "CreateExpl_Boss"
        ///</summary>
        [TestMethod()]
        public void CreateExpl_BossTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion bossExplosion;
            if(objectDirection != Vector3.Zero) objectDirection.Normalize();
            bossExplosion = BasicExplosion.CreateExpl_Boss(startPos, objectDirection, birthTime);
            Assert.IsTrue(bossExplosion.startPos == startPos);
            Assert.IsTrue(bossExplosion.objectDirection == objectDirection);
            Assert.IsTrue(bossExplosion.birthTime == birthTime);
            Assert.IsTrue(bossExplosion.maxTime == 20 * Explosion.MAX_TIME);
            Assert.IsTrue(bossExplosion.particleCount == (int)(5 * Explosion.EXPL_PARTICLE_GW));
            Assert.IsTrue(bossExplosion.particleSize == 10 * Explosion.PARTICLE_SIZE_GW);
            Assert.IsTrue(bossExplosion.totalSize == 10 * Explosion.TOTAL_SIZE_GW);
            Assert.IsTrue(bossExplosion.smoke == false);
            Assert.IsTrue(bossExplosion.explosionTexture != null);
        }


        /// <summary>
        ///Test for "CreateExpl_Enemy1"
        ///It's the same test for "CreateExpl_Enemy2", "CreateExpl_Enemy3", "CreateExpl_Enemy4" and "CreateExpl_Enemy5"
        ///</summary>
        [TestMethod()]
        public void CreateExpl_Enemy1Test()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion enemyExplosion;
            enemyExplosion = BasicExplosion.CreateExpl_Enemy1(startPos, objectDirection, birthTime);
            if(objectDirection != Vector3.Zero) objectDirection.Normalize();
            Assert.IsTrue(enemyExplosion.startPos == startPos);
            Assert.IsTrue(enemyExplosion.objectDirection == objectDirection);
            Assert.IsTrue(enemyExplosion.birthTime == birthTime);
            Assert.IsTrue(enemyExplosion.maxTime == 8 * Explosion.MAX_TIME);
            Assert.IsTrue(enemyExplosion.particleCount == (int)(2 * Explosion.EXPL_PARTICLE_GW));
            Assert.IsTrue(enemyExplosion.particleSize == 3 * Explosion.PARTICLE_SIZE_GW);
            Assert.IsTrue(enemyExplosion.totalSize == 3 * Explosion.TOTAL_SIZE_GW);
            Assert.IsTrue(enemyExplosion.smoke == false);
            Assert.IsTrue(enemyExplosion.explosionTexture != null);
        }


        /// <summary>
        ///Test for "CreateExpl_Laser"
        ///It's the same test for "CreateExplosion_Missile" and "CreateExplosion_Plasma".
        ///</summary>
        [TestMethod()]
        public void CreateExpl_LaserTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion weaponExplosion;
            if(objectDirection != Vector3.Zero) objectDirection.Normalize();
            weaponExplosion = BasicExplosion.CreateExpl_Laser(startPos, objectDirection, birthTime);
            Assert.IsTrue(weaponExplosion.startPos == startPos);
            Assert.IsTrue(weaponExplosion.objectDirection == objectDirection);
            Assert.IsTrue(weaponExplosion.birthTime == birthTime);
            Assert.IsTrue(weaponExplosion.maxTime == 5 * Explosion.MAX_TIME);
            Assert.IsTrue(weaponExplosion.particleCount == (int)(1 * Explosion.EXPL_PARTICLE_GW));
            Assert.IsTrue(weaponExplosion.particleSize == 2 * Explosion.PARTICLE_SIZE_GW);
            Assert.IsTrue(weaponExplosion.totalSize == 2 * Explosion.TOTAL_SIZE_GW);
            Assert.IsTrue(weaponExplosion.smoke == false);
            Assert.IsTrue(weaponExplosion.explosionTexture != null);
        }


        /// <summary>
        ///Test for "CreateExpl_Player"
        ///</summary>
        [TestMethod()]
        public void CreateExpl_PlayerTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion playerExplosion;
            if(objectDirection != Vector3.Zero) objectDirection.Normalize();
            playerExplosion = BasicExplosion.CreateExpl_Player(startPos, objectDirection, birthTime);
            Assert.IsTrue(playerExplosion.startPos == startPos);
            Assert.IsTrue(playerExplosion.objectDirection == objectDirection);
            Assert.IsTrue(playerExplosion.birthTime == birthTime);
            Assert.IsTrue(playerExplosion.maxTime == 10 * Explosion.MAX_TIME);
            Assert.IsTrue(playerExplosion.particleCount == (int)(2.5 * Explosion.EXPL_PARTICLE_GW));
            Assert.IsTrue(playerExplosion.particleSize == 5 * Explosion.PARTICLE_SIZE_GW);
            Assert.IsTrue(playerExplosion.totalSize == 5 * Explosion.TOTAL_SIZE_GW);
            Assert.IsTrue(playerExplosion.smoke == false);
            Assert.IsTrue(playerExplosion.explosionTexture != null);
        }


        /// <summary>
        ///Test for "Update"
        ///</summary>
        [TestMethod()]
        public void UpdateTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 500F;
            BasicExplosion explosion;
            explosion = BasicExplosion.CreateExpl_Boss(startPos, objectDirection, birthTime);
            explosion.Update();
            Assert.IsTrue(explosion.explosionVertices == null);
            Assert.IsTrue(explosion.deviceVertexBuffer == null);
            Assert.IsTrue(explosion.hasFinished == true);
        }


        /// <summary>
        ///Test for "HasFinished"
        ///</summary>
        [TestMethod()]
        public void HasFinishedTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 500F;
            BasicExplosion explosion;
            explosion = BasicExplosion.CreateExpl_Boss(startPos, objectDirection, birthTime);
            explosion.HasFinished();
            Assert.IsTrue(explosion.explosionVertices == null);
            Assert.IsTrue(explosion.deviceVertexBuffer == null);
            Assert.IsTrue(explosion.hasFinished == true);
        }


        /// <summary>
        ///Test for "CreateSmokeExpl_Weapon"
        ///</summary>
        [TestMethod()]
        public void CreateSmokeExpl_WeaponTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion weaponSmokeExplosion;
            if(objectDirection != Vector3.Zero) objectDirection.Normalize();
            weaponSmokeExplosion = BasicExplosion.CreateSmokeExpl_Weapon(startPos, objectDirection, birthTime);
            Assert.IsTrue(weaponSmokeExplosion.startPos == startPos);
            Assert.IsTrue(weaponSmokeExplosion.objectDirection == objectDirection);
            Assert.IsTrue(weaponSmokeExplosion.birthTime == birthTime);
            Assert.IsTrue(weaponSmokeExplosion.maxTime == 7 * Explosion.MAX_TIME);
            Assert.IsTrue(weaponSmokeExplosion.particleCount == (int)(1 * Explosion.EXPL_PARTICLE_GW));
            Assert.IsTrue(weaponSmokeExplosion.particleSize == 2 * Explosion.PARTICLE_SIZE_GW);
            Assert.IsTrue(weaponSmokeExplosion.totalSize == 2 * Explosion.TOTAL_SIZE_GW);
            Assert.IsTrue(weaponSmokeExplosion.smoke == true);
            Assert.IsTrue(weaponSmokeExplosion.explosionTexture != null);
        }


        /// <summary>
        ///Test for "CreateSmokeExpl_Player"
        ///</summary>
        [TestMethod()]
        public void CreateSmokeExpl_PlayerTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion playerSmokeExplosion;
            if(objectDirection != Vector3.Zero) objectDirection.Normalize();
            playerSmokeExplosion = BasicExplosion.CreateSmokeExpl_Player(startPos, objectDirection, birthTime);
            Assert.IsTrue(playerSmokeExplosion.startPos == startPos);
            Assert.IsTrue(playerSmokeExplosion.objectDirection == objectDirection);
            Assert.IsTrue(playerSmokeExplosion.birthTime == birthTime);
            Assert.IsTrue(playerSmokeExplosion.maxTime == 15 * Explosion.MAX_TIME);
            Assert.IsTrue(playerSmokeExplosion.particleCount == (int)(1 * Explosion.EXPL_PARTICLE_GW));
            Assert.IsTrue(playerSmokeExplosion.particleSize == 5 * Explosion.PARTICLE_SIZE_GW);
            Assert.IsTrue(playerSmokeExplosion.totalSize == 5 * Explosion.TOTAL_SIZE_GW);
            Assert.IsTrue(playerSmokeExplosion.smoke == true);
            Assert.IsTrue(playerSmokeExplosion.explosionTexture != null);
        }


        /// <summary>
        ///Test for "CreateSmokeExpl_Enemy"
        ///</summary>
        [TestMethod()]
        public void CreateSmokeExpl_EnemyTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion enemySmokeExplosion;
            if(objectDirection != Vector3.Zero) objectDirection.Normalize();
            enemySmokeExplosion = BasicExplosion.CreateSmokeExpl_Enemy(startPos, objectDirection, birthTime);
            Assert.IsTrue(enemySmokeExplosion.startPos == startPos);
            Assert.IsTrue(enemySmokeExplosion.objectDirection == objectDirection);
            Assert.IsTrue(enemySmokeExplosion.birthTime == birthTime);
            Assert.IsTrue(enemySmokeExplosion.maxTime == 10 * Explosion.MAX_TIME);
            Assert.IsTrue(enemySmokeExplosion.particleCount == (int)(2 * Explosion.EXPL_PARTICLE_GW));
            Assert.IsTrue(enemySmokeExplosion.particleSize == 3 * Explosion.PARTICLE_SIZE_GW);
            Assert.IsTrue(enemySmokeExplosion.totalSize == 3 * Explosion.TOTAL_SIZE_GW);
            Assert.IsTrue(enemySmokeExplosion.smoke == true);
            Assert.IsTrue(enemySmokeExplosion.explosionTexture != null);
        }


        /// <summary>
        ///Test for "CreateSmokeExpl_Boss"
        ///</summary>
        [TestMethod()]
        public void CreateSmokeExpl_BossTest()
        {
            Vector3 startPos = new Vector3(10, 10, 10);
            Vector3 objectDirection = Vector3.Zero;
            float birthTime = 1000F;
            BasicExplosion bossSmokeExplosion;
            if(objectDirection != Vector3.Zero) objectDirection.Normalize();
            bossSmokeExplosion = BasicExplosion.CreateSmokeExpl_Boss(startPos, objectDirection, birthTime);
            Assert.IsTrue(bossSmokeExplosion.startPos == startPos);
            Assert.IsTrue(bossSmokeExplosion.objectDirection == objectDirection);
            Assert.IsTrue(bossSmokeExplosion.birthTime == birthTime);
            Assert.IsTrue(bossSmokeExplosion.maxTime == 40 * Explosion.MAX_TIME);
            Assert.IsTrue(bossSmokeExplosion.particleCount == (int)(5 * Explosion.EXPL_PARTICLE_GW));
            Assert.IsTrue(bossSmokeExplosion.particleSize == 10 * Explosion.PARTICLE_SIZE_GW);
            Assert.IsTrue(bossSmokeExplosion.totalSize == 10 * Explosion.TOTAL_SIZE_GW);
            Assert.IsTrue(bossSmokeExplosion.smoke == true);
            Assert.IsTrue(bossSmokeExplosion.explosionTexture != null);
        }
    }
}
